package app.hzvmap.com.rangecontrol.utils.netty;

import android.util.Log;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.List;
import java.util.logging.Logger;

import app.hzvmap.com.rangecontrol.App;
import app.hzvmap.com.rangecontrol.model.Position;
import app.hzvmap.com.rangecontrol.utils.DbHelper;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.concurrent.GenericFutureListener;

public class LogPushUdpClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

//	private static Channel channel = LogPushUdpClient.getInstance().getChannel();

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        //当channel就绪后。
        Log.i("UDP", "client channel is ready!");
//       ctx.writeAndFlush("started");//阻塞直到发送完毕  这一块可以去掉的
//       NettyUdpClientHandler.sendMessage("你好UdpServer", new InetSocketAddress("127.0.0.1",8888));
//       sendMessageWithInetAddressList(message);
//       logger.info("client send message is: 你好UdpServer");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet)
            throws Exception {
        // TODO 不确定服务端是否有response 所以暂时先不用处理
        final ByteBuf buf = packet.content();
        int readableBytes = buf.readableBytes();
        byte[] content = new byte[readableBytes];
        buf.readBytes(content);
        String serverMessage = new String(content);

        if (serverMessage.startsWith("**T")) {//上发坐标反馈
            String[] datas = serverMessage.split("\\|");
            if (datas.length >= 2) {
                List<Position> positionList = App.POSITIONTEMP.get(datas[1]);
                DbHelper.getDb().delete(positionList);
                Log.d("UDP", "LogPushUdpClient Delete Point " + positionList.size());
            }
        }
        Log.i("UDP", "reserveServerResponse is: " + serverMessage);
    }


    /**
     * 向服务器发送消息
     *
     * @param msg               按规则拼接的消息串
     * @param inetSocketAddress 目标服务器地址
     */
    public static void sendMessage(final String msg, final InetSocketAddress inetSocketAddress) {
        if (msg == null) {
            throw new NullPointerException("msg is null");
        }
        // TODO 这一块的msg需要做处理 字符集转换和Bytebuf缓冲区
        senderInternal(datagramPacket(msg, inetSocketAddress));
    }


    /**
     * 组装数据包
     *
     * @param msg               消息串
     * @param inetSocketAddress 服务器地址
     * @return DatagramPacket
     */
    private static DatagramPacket datagramPacket(String msg, InetSocketAddress inetSocketAddress) {
        ByteBuf dataBuf = Unpooled.copiedBuffer(msg, Charset.forName("UTF-8"));
        DatagramPacket datagramPacket = new DatagramPacket(dataBuf, inetSocketAddress);
        return datagramPacket;
    }

    /**
     * 组装数据包
     *
     * @param bt                消息串
     * @param inetSocketAddress 服务器地址
     * @return DatagramPacket
     */
    private static DatagramPacket datagramPacket(byte[] bt, InetSocketAddress inetSocketAddress) {
        ByteBuf dataBuf = Unpooled.buffer();
        dataBuf.writeBytes(bt);
        DatagramPacket datagramPacket = new DatagramPacket(dataBuf, inetSocketAddress);
        return datagramPacket;
    }

    /**
     * 发送数据包服务器无返回结果
     *
     * @param datagramPacket
     */
    private static void senderInternal(final DatagramPacket datagramPacket) {
        Log.i("UDP", "LogPushUdpClient.channel" + LogPushUdpClient.channel);
        if (LogPushUdpClient.channel != null) {
            LogPushUdpClient.channel.writeAndFlush(datagramPacket).addListener(new GenericFutureListener<ChannelFuture>() {
                @Override
                public void operationComplete(ChannelFuture future)
                        throws Exception {
                    boolean success = future.isSuccess();
                    Log.i("UDP", "Sender datagramPacket result : " + success);
                }
            });
        } else {
            throw new NullPointerException("channel is null");
        }
    }

    public static void senderInternal(String msg, InetSocketAddress inetSocketAddress, final List<Position> positions) {
        Log.i("UDP", "LogPushUdpClient.channel=>" + LogPushUdpClient.channel + " add=>" + inetSocketAddress + " msg=>" + msg);
        if (LogPushUdpClient.channel != null) {
            ByteBuf dataBuf = Unpooled.copiedBuffer(msg, Charset.forName("UTF-8"));
            DatagramPacket datagramPacket = new DatagramPacket(dataBuf, inetSocketAddress);
            LogPushUdpClient.channel.writeAndFlush(datagramPacket).addListener(new GenericFutureListener<ChannelFuture>() {
                @Override
                public void operationComplete(ChannelFuture future)
                        throws Exception {
                    boolean success = future.isSuccess();
                    if (success && positions != null) {
                        for (Position p : positions) {
                            DbHelper.getDb().delete(p);
                        }
                    }
                    Log.i("UDP", "Sender datagramPacket result : " + success);
                }
            });
        } else {
            throw new NullPointerException("channel is null");
        }
    }

    public static void senderInternal(byte[] bt, InetSocketAddress inetSocketAddress) {
        Log.i("UDP", "LogPushUdpClient.channel" + LogPushUdpClient.channel);
        if (LogPushUdpClient.channel != null) {
            ByteBuf dataBuf = Unpooled.buffer();
            dataBuf.writeBytes(bt);
            DatagramPacket datagramPacket = new DatagramPacket(dataBuf, inetSocketAddress);
            LogPushUdpClient.channel.writeAndFlush(datagramPacket).addListener(new GenericFutureListener<ChannelFuture>() {
                @Override
                public void operationComplete(ChannelFuture future)
                        throws Exception {
                    boolean success = future.isSuccess();
                    Log.i("UDP", "Sender datagramPacket result : " + success);
                }
            });
        } else {
            throw new NullPointerException("channel is null");
        }
    }
}
